package com.yxw.live_vod_boot.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yxw.live_vod_boot.dto.FileDTO;
import com.yxw.live_vod_boot.entity.YxFileEntity;
import com.yxw.live_vod_boot.mapper.FileMapper;
import com.yxw.live_vod_boot.service.FileService;
import com.yxw.live_vod_boot.utils.HuaWeiObsUtil;
import com.yxw.live_vod_boot.utils.UserUtil;
import com.yxw.live_vod_boot.vo.YxFileVo;
import com.yxw.yxnet_cd_center.common.constant.CommonConstant;
import com.yxw.yxnet_cd_center.common.enums.CommonErrorEnum;
import com.yxw.yxnet_cd_center.common.enums.FileClassifyEnum;
import com.yxw.yxnet_cd_center.common.exception.BaseException;
import com.yxw.yxnet_cd_center.common.utils.FileUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;

/**
 * 文件管理
 * @author liuxin
 * @date 2023.11.15
 */
@Slf4j
@Service
public class FileServiceImpl extends ServiceImpl<FileMapper, YxFileEntity> implements FileService {

    /**
     * 视频文件最大大小
     */
    @Value("${file.video.max.size}")
    private long fileVideoMaxSize;

    /**
     * 视频文件最大个数
     */
    @Value("${file.video.max.count}")
    private long fileVideoMaxCount;
    /**
     * 图片文件最大大小
     */
    @Value("${file.image.max.size}")
    private long fileImageMaxSize;

    /**
     * 图片文件最大个数
     */
    @Value("${file.image.max.count}")
    private long fileImageMaxCount;

    @Autowired
    private FileMapper fileMapper;

    @Autowired
    private HuaWeiObsUtil huaWeiObsUtil;

    @Autowired
    private UserUtil userUtil;


    @Override
    public List<YxFileVo> uploadFile(MultipartFile[] multipartFiles, Long objId, Integer classify, String remark) {
        //主体校验
        if(null==objId){
            throw new BaseException("文件对应对象主体不能为空");
        }
        //文件类型校验
        FileClassifyEnum fileClassifyEnum = FileClassifyEnum.getEnumByCode(classify);
        Optional.ofNullable(fileClassifyEnum).orElseThrow(() -> new BaseException(CommonErrorEnum.FILE_TYPE_VERIFY_ERROR));
        //视频校验
        if(1==classify){
            for (MultipartFile multipartFile : multipartFiles) {
                if (multipartFile.getSize() > fileVideoMaxSize) {
                    throw new BaseException(CommonErrorEnum.FILE_SIZE_OUT_OF_RANG_ERROR.getCode(),CommonErrorEnum.FILE_SIZE_OUT_OF_RANG_ERROR.getType(),"不能上传超过" + fileVideoMaxSize / 1024.0 / 1024.0 + "M的视频");
                }
            }
            if (!FileUtils.checkVideoFileType(multipartFiles)) {
                throw new BaseException(CommonErrorEnum.FILE_TYPE_VERIFY_ERROR);
            }
        }else{
            //文件个数校验
            if (multipartFiles.length > fileImageMaxCount) {
                throw new BaseException(CommonErrorEnum.FILE_TYPE_VERIFY_ERROR, "不能上传超过" + fileImageMaxCount + "个图片");
            }
            //文件大小校验
            for (MultipartFile multipartFile : multipartFiles) {
                if (multipartFile.getSize() > fileImageMaxSize) {
                    throw new BaseException(CommonErrorEnum.FILE_SIZE_OUT_OF_RANG_ERROR, "不能上传超过" + fileImageMaxSize / 1024.0 / 1024.0 + "M的图片");
                }
            }
            //文件后缀名校验
            if (!FileUtils.checkImageFileType(multipartFiles)) {
                throw new BaseException(CommonErrorEnum.FILE_TYPE_VERIFY_ERROR);
            }
        }
        List<YxFileVo> voList=new ArrayList<>();
        for (MultipartFile multipartFile :multipartFiles) {
            try {
                //存储objectKey
                String objectKey = fileClassifyEnum.getPath() + UUID.randomUUID().toString().replace("-", "") + multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().lastIndexOf(CommonConstant.POINT));
                //上传附件
                String filePath = huaWeiObsUtil.uploadFile(objectKey, multipartFile.getInputStream());
                YxFileEntity entity = new YxFileEntity();
                entity.setObjectKey(objectKey);
                log.info("OBS文件objectKey:{},上传图片contentType:{}", objectKey, multipartFile.getContentType());
                String fileName = multipartFile.getOriginalFilename();
                entity.setCreateId(userUtil.getLoginUserId());
                entity.setCreateName(userUtil.getLoginName());
                entity.setCreateTime(new Date());
                entity.setFileUrl(filePath);
                entity.setBussId(objId);
                entity.setFileType(fileName.substring(fileName.lastIndexOf(CommonConstant.POINT), fileName.length()));
                entity.setFileSize(multipartFile.getSize());
                entity.setFileName(fileName);
                entity.setRemark(remark);
                this.save(entity);
                //属性复制
                YxFileVo vo = new YxFileVo();
                BeanUtil.copyProperties(entity, vo);
                voList.add(vo);
            }catch (Exception e){
                log.error("上传异常",e);
                throw new BaseException("上传异常"+e.getMessage());
            }
        }
        return voList;
    }

    /**
     * 文件删除
     * @param dto
     */
    @Override
    public void deleteFile(FileDTO dto) {
        List<Long> fileIdList = dto.getFileIdList();
        Long objId = dto.getObjId();
        if(null==objId && (fileIdList==null || fileIdList.isEmpty())){
            throw new BaseException("附件删除时对应主体ID和附件ID不能都为空");
        }
        //删除华为云服务器上附件文件
        LambdaQueryWrapper<YxFileEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(null!=objId, YxFileEntity::getBussId,objId).or().in(null!=fileIdList && !fileIdList.isEmpty(),YxFileEntity::getId,fileIdList);
        List<YxFileEntity> entityList = baseMapper.selectList(queryWrapper);
        if(null!=entityList && !entityList.isEmpty()){
            for (YxFileEntity entity :entityList) {
                huaWeiObsUtil.deleteFile(entity.getObjectKey());
            }
            //删除本地文件信息
            if(null!=objId){
                LambdaQueryWrapper<YxFileEntity> deletWrapper = new LambdaQueryWrapper<>();
                deletWrapper.eq(true, YxFileEntity::getBussId,objId);
                baseMapper.delete(deletWrapper);
            }else{
                baseMapper.deleteBatchIds(fileIdList);
            }
        }else{
            throw new BaseException("删除文件为空");
        }
    }

    /**
     * 文件下载/预览
     * @param dto
     * @return
     */
    @Override
    public String downloadFile(FileDTO dto) {
        List<Long> fileIdList = dto.getFileIdList();
        Long objId = dto.getObjId();
        if(null==objId && (fileIdList==null || fileIdList.isEmpty())){
            throw new BaseException("附件下载时对应主体ID和附件ID不能都为空");
        }
        LambdaQueryWrapper<YxFileEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(null!=objId, YxFileEntity::getBussId,objId).or().in(null!=fileIdList && !fileIdList.isEmpty(),YxFileEntity::getId,fileIdList);
        List<YxFileEntity> entityList = baseMapper.selectList(queryWrapper);
        if(null!=entityList && !entityList.isEmpty()){
            YxFileEntity entity = entityList.get(0);
            return entity.getFileUrl();
        }else{
            throw new BaseException("下载文件未找到对应信息");
        }
    }

    /**
     * 根据业务ID获取文件信息列表
     * @param bussId
     * @return
     */
    @Override
    public List<YxFileVo> getFileListByBussId(Long bussId) {
        LambdaQueryWrapper<YxFileEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(bussId != null, YxFileEntity::getBussId, bussId);
        List<YxFileEntity> entityList = baseMapper.selectList(queryWrapper);
        List<YxFileVo> voList = new ArrayList<>();
        if (null != entityList && !entityList.isEmpty()) {
            voList = BeanUtil.copyToList(entityList, YxFileVo.class);
        }
        return voList;
    }
}
